package com.njust.RateMyTray_backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.njust.RateMyTray_backend.common.ForbiddenException;
import com.njust.RateMyTray_backend.dto.StatisticsQueryDTO;
import com.njust.RateMyTray_backend.entity.Comment;
import com.njust.RateMyTray_backend.entity.Window;
import com.njust.RateMyTray_backend.mapper.CommentMapper;
import com.njust.RateMyTray_backend.mapper.DishMapper;
import com.njust.RateMyTray_backend.mapper.WindowMapper;
import com.njust.RateMyTray_backend.service.CommentService;
import com.njust.RateMyTray_backend.service.StatisticsService;
import com.njust.RateMyTray_backend.service.WindowService;
import com.njust.RateMyTray_backend.vo.CommentTrendVO;
import com.njust.RateMyTray_backend.vo.DishRatingVO;
import com.njust.RateMyTray_backend.vo.PopularWindowVO;
import com.njust.RateMyTray_backend.vo.MerchantStatisticsVO;
import com.njust.RateMyTray_backend.vo.StatisticsVO;
import com.njust.RateMyTray_backend.vo.TopRatedDishVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.List;

@Service
public class StatisticsServiceImpl implements StatisticsService {
    
    @Autowired
    private CommentMapper commentMapper;
    
    @Autowired
    private WindowMapper windowMapper;
    
    @Autowired
    private DishMapper dishMapper;
    
    @Autowired
    private CommentService commentService;
    
    @Autowired
    private WindowService windowService;

    @Override
    public StatisticsVO getPlatformStatistics(StatisticsQueryDTO queryDTO) {
        
        // 1. 获取基础统计数据
        BigDecimal overallAverageRating = commentMapper.getOverallAverageRating(queryDTO.getStartDate(), queryDTO.getEndDate());
        
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        if (queryDTO.getStartDate() != null) queryWrapper.ge("commented_at", queryDTO.getStartDate());
        if (queryDTO.getEndDate() != null) queryWrapper.le("commented_at", queryDTO.getEndDate());
        long totalComments = commentService.count(queryWrapper);
        
        Long positiveComments = commentMapper.countPositiveComments(queryDTO.getStartDate(), queryDTO.getEndDate());
        
        BigDecimal positiveCommentRate = BigDecimal.ZERO;
        if (totalComments > 0) {
            positiveCommentRate = new BigDecimal(positiveComments)
                    .divide(new BigDecimal(totalComments), 4, RoundingMode.HALF_UP);
        }
        
        // 2. 获取排行数据 (排行数据通常不按时间筛选，以反映总体情况)
        List<PopularWindowVO> mostPopularWindows = windowMapper.findMostPopularWindows();
        List<TopRatedDishVO> topRatedDishes = dishMapper.findTopRatedDishes();

        // 3. 组装VO
        return StatisticsVO.builder()
                .overallAverageRating(overallAverageRating.setScale(2, RoundingMode.HALF_UP))
                .totalComments(totalComments)
                .positiveCommentRate(positiveCommentRate)
                .mostPopularWindows(mostPopularWindows)
                .topRatedDishes(topRatedDishes)
                .build();
    }

    @Override
    public MerchantStatisticsVO getMerchantStatistics(Long windowId, Long merchantId) {
        // 1. 权限验证
        Window window = windowService.getById(windowId);
        if (window == null || !window.getMerchantId().equals(merchantId)) {
            throw new ForbiddenException("无权限访问此窗口的统计数据");
        }
        
        // 2. 获取数据
        LocalDate startDate = LocalDate.now().minusDays(7);
        List<CommentTrendVO> commentTrend = commentMapper.getCommentTrend(windowId, "window", startDate);
        List<DishRatingVO> dishRatings = dishMapper.findDishRatingsByWindowId(windowId);
        
        // 3. 组装VO
        return MerchantStatisticsVO.builder()
                .windowId(window.getId())
                .windowName(window.getWindowName())
                .averageRating(window.getAverageRating())
                .totalComments((long) window.getRatingCount())
                .commentTrend(commentTrend)
                .dishRatings(dishRatings)
                .build();
    }
} 